/**
* Oxide
*
* Copyright (c) 2011 Dinosaur Kick Pty Ltd, All rights reserved.
*
* This source code is made available under the "Modified BSD" licensing arrangement.
* See license.txt for details.
*/
// ----------------------------------------------------------------------------

class_member_ptr parse_class_member(void)
{
	assert(m_cursor->identity == TOK_ACCESS_MODIFIER);
	string_type access = m_cursor->content;
	string_type doc_block = m_cursor.incrementer().doc_block;
	m_cursor.advance();
	
	if (m_cursor->identity == TOK_VAR)
	{
		return parse_member_var(access, doc_block);
	}
	else if (m_cursor->identity == TOK_METHOD)
	{
		return parse_method(access, doc_block);
	}

	unexpected_token_error(TOK_VAR, TOK_METHOD);
	return class_member_ptr();
}

// ----------------------------------------------------------------------------

method_ptr parse_method(const string_type& access, const string_type& doc_block)
{
	assert(m_cursor->identity == TOK_METHOD);

	method_ptr member = boost::make_shared<method_type>();
	member->access = access;
	member->doc_block = doc_block;

	m_cursor.advance();

	member->is_static = parse_flag(TOK_STATIC);
	member->is_abstract = parse_flag(TOK_ABSTRACT);
	member->is_final = parse_flag(TOK_FINAL);
	member->type = parse_expr();
	
	if (m_cursor->identity != TOK_IDENTIFIER)
	{
		unexpected_token_error(TOK_IDENTIFIER);
		m_cursor.advance_to(TOK_OPEN_PAREN);
	}
	else
	{
		member->name = m_cursor->content;
		m_cursor.advance();

		if (member->is_abstract && member->is_final)
		{
			error
			(
				O2_FORMAT("Method %s can not be declared both STATIC and FINAL.")
					% member->name
			);
		}
	}

	if (m_cursor->identity != TOK_OPEN_PAREN)
	{
		unexpected_token_error(TOK_OPEN_PAREN);
		return member;
	}
	
	m_cursor.advance();

	if (m_cursor->identity != TOK_CLOSE_PAREN)
	{
		unexpected_token_error(TOK_CLOSE_PAREN);
		return member;
	}
	
	m_cursor.advance();
	
	member->stmt_block = parse_stmt_block();
	
	return member;
}

// ----------------------------------------------------------------------------

member_var_ptr parse_member_var(const string_type& access, const string_type& doc_block)
{
	assert(m_cursor->identity == TOK_VAR);

	member_var_ptr member = boost::make_shared<member_var_type>();
	member->access = access;
	member->doc_block = doc_block;

	m_cursor.advance();

	member->is_static = parse_flag(TOK_STATIC);
	member->type = parse_expr();

	if (m_cursor->identity != TOK_IDENTIFIER)
	{
		unexpected_token_error(TOK_IDENTIFIER);
		return member;
	}

	member->name = m_cursor->content;
	m_cursor.advance();

	if (m_cursor->identity == TOK_ASSIGN)
	{
		m_cursor.advance();
		member->default_value = parse_expr();
	}

	if (m_cursor->identity != TOK_SEMICOLON)
	{
		unexpected_token_error(TOK_SEMICOLON);
		return member;
	}

	m_cursor.advance();
	return member;
}

// ----------------------------------------------------------------------------
